from flask import Flask, request, jsonify, Response
from flask_sqlalchemy import SQLAlchemy
from flask_cors import CORS
import uuid
import re
from datetime import datetime
from AutoEvl import *
from AutoLogin import *
from CheckUser import *
import os
import json

# 初始化数据库和文件上传路径
db = SQLAlchemy()
UPLOAD_FOLDER = 'uploads'
os.makedirs(UPLOAD_FOLDER, exist_ok=True)

# 数据库模型
class User(db.Model):
    __tablename__ = 'users'
    id = db.Column(db.Integer, primary_key=True)
    student_id = db.Column(db.String(50), unique=True, nullable=False)
    activation_code = db.Column(db.String(50), nullable=False)

# 初始化 Flask 应用
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://wuyuuser:wuyuyyds@47.238.86.58:3306/wuyu'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db.init_app(app)
# 允许跨域请求
CORS(app)

# 存储 token 和 student_id 的字典
process_tokens = {}
process_sid = {}

# 登录接口
@app.route('/login', methods=['POST'])
def login():
    data = request.get_json()
    if data is None:
        return jsonify({"message": "请求体必须是 JSON 格式"}), 400

    student_id = data.get('studentId')
    password = data.get('password')
    result = run(student_id, password)
    return jsonify(result)

# 文件上传接口
@app.route('/upload', methods=['POST'])
def upload_file():
    token = request.form.get('token')
    student_id = request.form.get('studentId')

    # 检查 token
    if not token:
        return jsonify({"code": 401, "message": "缺少 token"}), 200

    # 验证 token
    code = get_info(token)
    if code != 200:
        return jsonify({"code": 401, "message": "身份过期，请重新登录！"}), 200

    # 检查是否有文件被上传
    if 'file' not in request.files:
        return jsonify({"code": 401, "message": "没有文件被上传"}), 200

    files = request.files.getlist('file')
    if not files:
        return jsonify({"code": 401, "message": "未选择文件"}), 200

    upload_path = os.path.join(UPLOAD_FOLDER, student_id)
    os.makedirs(upload_path, exist_ok=True)

    filenames = []
    for file in files:
        if file.filename == '':
            return jsonify({"code": 401, "message": "未选择文件"}), 200

        match = re.match(r'(\d+)_', file.filename)
        if match:
            new_filename = f"{match.group(1)}.jpg"
            file_path = os.path.join(upload_path, new_filename)
            file.save(file_path)
            filenames.append(new_filename)

    return jsonify({"code": 200, "message": "文件上传成功", "filenames": filenames}), 200

# 启动评估任务接口
@app.route('/start', methods=['POST'])
def start():
    data = request.get_json()
    student_id = data.get('studentId')
    activation_code = data.get('activatedCode')
    token = data.get('token')

    # 验证 token
    code = get_info(token)
    if code != 200:
        return jsonify({"code": 401, "message": "身份过期，请重新登录！"}), 200

    user = User.query.filter_by(student_id=student_id, activation_code=activation_code).first()
    if user:
        process_id = str(uuid.uuid4())
        process_tokens[process_id] = token
        process_sid[process_id] = student_id
        return jsonify({"processId": process_id})
    else:
        return jsonify({"message": "账号或激活码错误"}), 401

# 获取实时日志接口
@app.route('/logs/<process_id>', methods=['GET'])
def get_logs(process_id):
    token = process_tokens.get(process_id)
    student_id = process_sid.get(process_id)
    if token is None or student_id is None:
        return jsonify({"message": "无效的进程 ID"}), 404

    def generate():
        start_time = datetime.now()
        folder_path = os.path.join(UPLOAD_FOLDER, student_id)

        if not os.path.exists(folder_path):
            yield f"data: {json.dumps({'message': {'msg': '文件夹不存在！', 'code': 500}, 'studentId': '未上传'})}\n\n"
            return

        for filename in os.listdir(folder_path):
            if filename.lower().endswith('.jpg'):
                file_path = os.path.join(folder_path, filename)
                url = decode_qrcode(file_path)

                transcript_id, hash_value = extract_params(url)
                if transcript_id and hash_value:
                    logs = submit_evaluation(transcript_id, hash_value, token)
                    current_time = datetime.now().strftime('%Y年%m月%d日 %H时%M分%S秒')
                    yield f"data: {json.dumps({'message': logs, 'studentId': os.path.splitext(filename)[0], 'time': current_time})}\n\n"

        end_time = datetime.now()
        total_seconds = (end_time - start_time).total_seconds()
        # 格式化 end_time 为字符串
        formatted_end_time = end_time.strftime('%Y-%m-%d %H:%M:%S')
        # 发送完成信息，包括总时间和结束时间
        yield f"data: {json.dumps({'message': {'msg': '所有文件处理完成！', 'code': 'COMPLETED'}, 'totalTime': str(total_seconds), 'studentId': '', 'time': formatted_end_time})}\n\n"

    return Response(generate(), mimetype='text/event-stream')

# 验证 token 接口
@app.route('/validate-token', methods=['POST'])
def validate_token():
    token = request.json.get('token')
    studentId = request.json.get('studentId')
    if not token:
        return jsonify({"code": 400, "message": "缺少 token"}), 400

    code = get_info(token)
    task_info = len(os.listdir(os.path.join(UPLOAD_FOLDER, studentId))) if os.path.exists(os.path.join(UPLOAD_FOLDER, studentId)) else 0

    if code == 200:
        return jsonify({"code": 200, "message": "token验证成功", "task": task_info}), 200
    else:
        return jsonify({"code": 401, "message": "token验证失败"}), 401

# 启动 Flask 应用
if __name__ == '__main__':
    with app.app_context():
        db.create_all()
    app.run(host='0.0.0.0', port=5000, debug=True)
